package cc.minos.game
{
	import flash.display.Sprite;
	import flash.events.EventDispatcher;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	/**
	 * ...
	 * @author Minos
	 */
	public class GridGame
	{
		//方块类
		private var pieceClass:Class;
		//纵
		public var cols:uint;
		//横
		public var rows:uint;
		//间隔
		public var spacing:Number;
		//容器
		public var continer:Sprite;
		//频率
		protected var timer:Timer;
		//数据
		protected var grid:Array;
		
		/**
		 * 构造函数
		 * @param	continer	:	容器
		 * @param	cols		:	纵
		 * @param	rows		:	横
		 * @param	spacing		:	间隔
		 * @param	pieceClass	:	方块类
		 * @param	rate		:	频率
		 */
		public function GridGame( continer:Sprite , cols:int , rows:int , spacing:Number , pieceClass:Class , rate:Number = 30 )
		{
			this.continer = continer;
			this.cols = cols;
			this.rows = rows;
			this.spacing = spacing;
			this.pieceClass = pieceClass;
			
			if ( continer == null || cols <= 0 || rows <= 0 || pieceClass == null )
				throw new Error( 'GridGame参数错误。' );
			
			grid = [];
			for ( var i:int = 0 ; i < cols ; i++ )
			{
				grid.push( new Vector.<Piece>() );
			}
			
			setUpGrid();
			
			//1秒30次
			timer = new Timer( 1000 / rate , 0 );
			timer.addEventListener( TimerEvent.TIMER , onTimer );
		}
		
		protected function setUpGrid():void
		{
		}
		
		protected function onTimer( e:TimerEvent ):void
		{
		}
		
		/**
		 * 添加
		 * @param	col		:	纵(x)
		 * @param	row		:	横(y)
		 * @return
		 */
		public function addPiece( col:uint , row:uint ):Piece
		{
			var p:Piece = new pieceClass();
			p.x = col * spacing , p.y = row * spacing;
			p.col = col , p.row = row;
			continer.addChild( p );
			grid[ col ][ row ] = p;
			return p;
		}
		
		/**
		 * 删除
		 * @param	col		:	纵(x)
		 * @param	row		:	横(y)
		 * @return
		 */
		public function removePiece( col:uint , row:uint ):Piece
		{
			var p:Piece = grid[ col ][ row ];
			if ( p == null )
				return null;
			if ( continer.contains( p ) )
			{
				p.destroy();
			}
			grid[ col ][ row ] = null;
			return p;
		}
		
		/**
		 * 换位置
		 * @param	p1
		 * @param	p2
		 */
		public function swapPieces( p1:Piece , p2:Piece ):void
		{
			var tempCol:int = p1.col;
			var tempRow:int = p1.row;
			p1.col = p2.col;
			p1.row = p2.row;
			p2.col = tempCol;
			p2.row = tempRow;
			grid[ p1.col ][ p1.row ] = p1;
			grid[ p2.col ][ p2.row ] = p2;
		}
		
		/**
		 *
		 * @param	col
		 * @param	row
		 * @param	mustHave
		 * @param	needOne
		 */
		public function matchPattern( col:uint , row:uint , mustHave:Array , needOne:Array ):Boolean
		{
			var thisType:int = grid[ col ][ row ].type;
			
			// make sure this has all must-haves
			for ( var i:int = 0 ; i < mustHave.length ; i++ )
			{
				if ( !matchType( col + mustHave[ i ][ 0 ] , row + mustHave[ i ][ 1 ] , thisType ) )
				{
					return false;
				}
			}
			
			// make sure it has at least one need-ones
			for ( i = 0 ; i < needOne.length ; i++ )
			{
				if ( matchType( col + needOne[ i ][ 0 ] , row + needOne[ i ][ 1 ] , thisType ) )
				{
					return true;
				}
			}
			return false;
		}
		
		/**
		 *
		 * @param	col
		 * @param	row
		 * @param	type
		 */
		public function matchType( col:uint , row:uint , type:int ):Boolean
		{
			if (( col < 0 ) || ( col > ( cols - 1 ) ) || ( row < 0 ) || ( row > ( rows - 1 ) ) )
				return false;
			return ( grid[ col ][ row ].type == type );
		}
		
		/**
		 * 开始
		 */
		public function start():void
		{
			timer.start();
		}
		
		/**
		 * 停止
		 */
		public function stop():void
		{
			timer.stop();
		}
		
		/**
		 * 清除
		 */
		public function cleanUp():void
		{
			grid = null
			while ( continer.numChildren > 0 )
			{
				continer.removeChildAt( 0 );
			}
			timer.stop();
			timer.removeEventListener( TimerEvent.TIMER , onTimer );
			timer = null;
		}
	}

}